package cn.mw.cmdb.link.service.impl;

import cn.mw.cmdb.exception.WarnTitleException;
import cn.mw.cmdb.link.entity.*;
import cn.mw.cmdb.link.enums.LinkDetectionWayEnum;
import cn.mw.cmdb.link.enums.LinkFetchPortEnum;
import cn.mw.cmdb.link.param.LinkParam;
import cn.mw.cmdb.link.service.LinkBandWidthManager;
import cn.mw.cmdb.link.service.LinkImportManager;
import cn.mw.cmdb.link.service.MwNetWorkLinkService;
import cn.mw.cmdb.link.strategy.manager.LinkDetectionWayManage;
import cn.mw.cmdb.mongoMapper.MwLinkTreeMapper;
import cn.mw.cmdb.mongoMapper.MwNetWorkLinkMapper;
import cn.mw.cmdb.param.InstanceIdsParam;
import cn.mw.cmdb.param.zabbixResult.ItemApplication;
import cn.mw.cmdb.service.impl.BaseSearchService;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.InstanceServiceImpl;
import cn.mw.cmdb.template.utils.TemplateSortUtil;
import cn.mw.cmdb.util.AlphanumericComparator;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.components.mongodb.entity.SearchParam;
import cn.mw.components.mongodb.tool.CriteriaWrapper;
import cn.mw.main.api.common.ZabbixDubboService;
import cn.mw.microMonitorCommon.api.cmdb.*;
import cn.mw.microMonitorCommon.constants.ZabbixApiConstants;
import cn.mw.microMonitorCommon.entity.UnitResult;
import cn.mw.microMonitorCommon.entity.zabbix.MWZabbixAPIResult;
import cn.mw.microMonitorCommon.security.utils.SecurityUtils;
import cn.mw.microMonitorCommon.util.*;
import cn.mw.microMonitorCommon.utils.DatabaseUtils;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description 线路功能实现
 */
@Slf4j
@Service
public class MwNetWorkLinkServiceImpl extends BaseSearchService<MwNetWorkLinkDto> implements MwNetWorkLinkService {

    private MwNetWorkLinkMapper netWorkLinkMapper;

    private ModuleIDManager moduleIDManager;

    private LinkDetectionWayManage detectionWayManage;
    private MwLinkTreeMapper linkTreeMapper;

    private LinkImportManager linkImportManager;

    @DubboReference(check = false, timeout = 120000)
    public ZabbixDubboService zabbixDubboService;

    public CmdbServiceManage cmdbServiceManage;

    private LinkBandWidthManager bandWidthManager;

    private final String INTERFACE_BANDWIDTH = "INTERFACE_BANDWIDTH";//带宽监控项

    public final String ABNORMAL = "异常";//异常

    @DubboReference(check = false, timeout = 120000, mock = "true")
    private AssetsService assetsService;

    public MwNetWorkLinkServiceImpl(MwNetWorkLinkMapper netWorkLinkMapper, ModuleIDManager moduleIDManager, LinkDetectionWayManage detectionWayManage,
                                    MwLinkTreeMapper linkTreeMapper,CmdbServiceManage cmdbServiceManage,LinkImportManager linkImportManager,
                                    LinkBandWidthManager bandWidthManager) {
        this.netWorkLinkMapper = netWorkLinkMapper;
        this.moduleIDManager = moduleIDManager;
        this.detectionWayManage = detectionWayManage;
        this.linkTreeMapper = linkTreeMapper;
        this.cmdbServiceManage = cmdbServiceManage;
        this.linkImportManager = linkImportManager;
        this.bandWidthManager = bandWidthManager;
    }

    @Override
    public void saveLink(MwNetWorkLinkDto netWorkLinkDto) throws Exception {
        //名称校验
        Query query = new Query();
        query.addCriteria(new Criteria(CMDBTool.getFieldName(MwNetWorkLinkDto::getLinkName)).is(netWorkLinkDto.getLinkName()));
        if(!org.springframework.util.StringUtils.isEmpty(netWorkLinkDto.getLinkId())){
            query.addCriteria(new Criteria(CMDBTool.getFieldName(MwNetWorkLinkDto::getLinkId)).ne(netWorkLinkDto.getLinkId()));
        }
        long count = netWorkLinkMapper.count(query);
        if(count > 0){
            throw new WarnTitleException("time-plan-name-check");
        }
        if(StringUtils.isEmpty(netWorkLinkDto.getLinkId())){
            netWorkLinkDto.setLinkId(moduleIDManager.getIDStr(IDModelType.MyMonitor));
            netWorkLinkDto.setCreateTime(new Date());
            netWorkLinkDto.setCreater(SecurityUtils.getUser().getNickName());
        }else{
            netWorkLinkDto.setModificationTime(new Date());
            netWorkLinkDto.setModifier(SecurityUtils.getUser().getNickName());
        }
        //处理添加的线路数据
        LinkDetectionWayEnum detectionWayEnum = LinkDetectionWayEnum.getLinkDelectionWayEnum(netWorkLinkDto.getDetectionWay());
        detectionWayManage.handlerLinkData(detectionWayEnum,netWorkLinkDto);
        netWorkLinkMapper.save(netWorkLinkDto);
        //修改带宽
        bandWidthManager.editorBandWidth(netWorkLinkDto,this,zabbixDubboService);
    }

    @Override
    public void delLink(LinkParam linkParam) throws Exception {
        //判断是否需要删除ICMP类型资产
        if(linkParam.getIsDelIcmpAssets() != null && linkParam.getIsDelIcmpAssets()){
            deleteIcmpAssets(linkParam.getLinkIds());
        }
        //删除zabbix线路数据
        Query query = new Query();
        query.addCriteria(new Criteria(CMDBTool.getFieldName(MwNetWorkLinkDto::getLinkId)).in(linkParam.getLinkIds()));
        netWorkLinkMapper.remove(query);
    }

    private void deleteIcmpAssets(List<String> linkIds) throws Exception {
        //查询
        Query query = new Query();
        query.addCriteria(CriteriaWrapper.where(MwNetWorkLinkDto::getLinkId).in(linkIds));
        List<MwNetWorkLinkDto> linkDtos = netWorkLinkMapper.find(query);
        if(CollectionUtils.isEmpty(linkDtos)){return;}
        //获取ICMP检测的数据
        List<MwNetWorkLinkDto> icmpLinkDtos = linkDtos.stream().filter(item -> StringUtils.isNotEmpty(item.getDetectionWay()) && item.getDetectionWay().equals(LinkDetectionWayEnum.ICMP.getType())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(icmpLinkDtos)){return;}
        //取目标资产ID
        List<String> assetsIds = icmpLinkDtos.stream().filter(item -> StringUtils.isNotEmpty(item.getDetectionTargetIpId())).map(s -> s.getDetectionTargetIpId()).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(assetsIds)){return;}
        //根据资产ID删除资产
        InstanceIdsParam instanceIdsParam = new InstanceIdsParam();
        instanceIdsParam.setIds(assetsIds);
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        instanceService.doBatchRemove(instanceIdsParam);
    }

    @Override
    public Page selectList(LinkParam linkParam) throws Exception {
        Query query = new Query();
        if(StringUtils.isNotEmpty(linkParam.getLinkName())){
            query.addCriteria(CriteriaWrapper.where(MwNetWorkLinkDto::getLinkName).regex(linkParam.getLinkName()));
        }
        if(linkParam.getLinkIds() != null){
            query.addCriteria(CriteriaWrapper.where(MwNetWorkLinkDto::getLinkId).in(linkParam.getLinkIds()));
        }
        if(StringUtils.isNotEmpty(linkParam.getSourceDeviceIp())){
            query.addCriteria(CriteriaWrapper.where(MwNetWorkLinkDto::getSourceDeviceIp).regex(linkParam.getSourceDeviceIp()));
        }
        if(StringUtils.isNotEmpty(linkParam.getDetectionTargetIp())){
            query.addCriteria(CriteriaWrapper.where(MwNetWorkLinkDto::getDetectionTargetIp).regex(linkParam.getDetectionTargetIp()));
        }
        List<MwNetWorkLinkDto> linkDtos = netWorkLinkMapper.find(query);
        if(CollectionUtils.isEmpty(linkDtos)){return new Page();}
        Page page = pageHandle(linkDtos, linkParam.getPageNum(), linkParam.getPageSize());
        List<MwNetWorkLinkDto> dtos = page.getRecords();
        //按照检测方式分组
        Map<String, List<MwNetWorkLinkDto>> detectionWayGroupMap = dtos.stream().filter(item -> StringUtils.isNotEmpty(item.getDetectionWay())).collect(Collectors.groupingBy(item -> item.getDetectionWay()));
        for (Map.Entry<String, List<MwNetWorkLinkDto>> entry : detectionWayGroupMap.entrySet()) {
            String detectionWay = entry.getKey();
            LinkDetectionWayEnum detectionWayEnum = LinkDetectionWayEnum.getLinkDelectionWayEnum(detectionWay);
            detectionWayManage.getLinkDetectionData(detectionWayEnum,entry.getValue());
        }
        for (MwNetWorkLinkDto dto : dtos) {
            if(StringUtils.isEmpty(dto.getStatus())){
                dto.setStatus(ABNORMAL);
            }
            if(CollectionUtils.isEmpty(dto.getGroups())){
                dto.setGroups(new ArrayList<>());
            }
        }
        if(StringUtils.isNotEmpty(linkParam.getStatus())){
            dtos = dtos.stream().filter(item->StringUtils.isNotEmpty(item.getStatus()) && item.getStatus().equals(linkParam.getStatus())).collect(Collectors.toList());
        }
        List realData = handlerAssociationLabel(dtos);
        //排序处理
        if(StringUtils.isNotEmpty(linkParam.getSortName()) && StringUtils.isNotEmpty(linkParam.getSortOrder())){
            SearchParam searchParam = new SearchParam();
            searchParam.setSortName(linkParam.getSortName());
            searchParam.setSortOrder(linkParam.getSortOrder());
            realData = TemplateSortUtil.templateSortList(realData, searchParam, null);
        }
        page.setRecords(realData);
        return page;
    }

    private List handlerAssociationLabel(List<MwNetWorkLinkDto> dtos) {
        List realData = new ArrayList();
        for (MwNetWorkLinkDto dto : dtos) {
            List<LinkLabelDto> associationData = dto.getAssociationData();
            Map map = ListMapObjUtils.beanToMap(dto);
            if (CollectionUtils.isEmpty(associationData)) {
                realData.add(map);
                continue;
            }
            for (LinkLabelDto associationDatum : associationData) {
                map.put(associationDatum.getId(),associationDatum.getData());
            }
            realData.add(map);
        }
        return realData;
    }

    private Page pageHandle(List<MwNetWorkLinkDto> linkDtos,Integer pageNum,Integer pageSize){
        if(CollectionUtils.isNotEmpty(linkDtos)){
            int fromIndex = pageSize * (pageNum -1);
            int toIndex = pageSize * pageNum;
            if(toIndex > linkDtos.size()){
                toIndex = linkDtos.size();
            }
            List<MwNetWorkLinkDto> workLinkDtos = linkDtos.subList(fromIndex, toIndex);
            Page page = new Page();
            page.setRecords(workLinkDtos);
            page.setTotal(linkDtos.size());
            return page;
        }
        return new Page();
    }

    @Override
    public MwLinkIpAndInterfaceDto getDeviceIpAndInterface(LinkParam linkParam) throws Exception {
        MwLinkIpAndInterfaceDto dto = new MwLinkIpAndInterfaceDto();
        //获取资产对应的IP信息
        QueryAssetsInterfaceParam param = new QueryAssetsInterfaceParam();
        param.setInstanceId(linkParam.getInstanceId());
        List<AssetsInterfaceView> assetsInterfaceViews = assetsService.listAssetsInterfaces(param);
        if(CollectionUtils.isEmpty(assetsInterfaceViews)){return dto;}
        Set<String> ipList = assetsInterfaceViews.stream().filter(item -> item.getIp() != null).map(s -> s.getIp()).collect(Collectors.toSet());
        dto.setIpAddress(new ArrayList<>(ipList));
        List<AssetsInterfaceView> interfaceViews = assetsInterfaceViews.stream().filter(item -> item.getName() != null).collect(Collectors.toList());
        List<MwLinkInterfaceDto> interfaces = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(interfaceViews)){
            for (AssetsInterfaceView interfaceView : interfaceViews) {
                MwLinkInterfaceDto interfaceDto = new MwLinkInterfaceDto();
                interfaceDto.setInterfaceName(interfaceView.getName());
                interfaceDto.setInterfaceStatus(interfaceView.getState());
                interfaceDto.setInterfaceIpAddress(interfaceView.getIp());
                interfaces.add(interfaceDto);
            }
        }
        Collections.sort(interfaces,new AlphanumericComparator(CMDBTool.getFieldName(MwLinkInterfaceDto::getInterfaceName),null,"ASC"));
        dto.setInterfaces(interfaces);
        return dto;
    }

    /**
     * 获取线路带宽信息
     * @param linkParam
     * @return
     */
    @Override
    public MwLinkBandWidthDto getLinkBandWidthInfo(LinkParam linkParam) {
        MwLinkBandWidthDto bandWidthDto = new MwLinkBandWidthDto();
        if(StringUtils.isEmpty(linkParam.getHostId()) || linkParam.getServerId() == null || StringUtils.isEmpty(linkParam.getInterfaceName())){return bandWidthDto;}
        //查询zabbix 带宽数据
        MWZabbixAPIResult mwZabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_TYPE, linkParam.getServerId(), "[" + linkParam.getInterfaceName() + "]" + INTERFACE_BANDWIDTH, linkParam.getHostId(), true);
        if(mwZabbixAPIResult == null ||mwZabbixAPIResult.isFail()){return bandWidthDto;}
        List<ItemApplication> applicationList = JSONArray.parseArray(String.valueOf(mwZabbixAPIResult.getData()), ItemApplication.class);
        if(CollectionUtils.isEmpty(applicationList)){return bandWidthDto;}
        ItemApplication itemApplication = applicationList.get(0);
        //单位转换
        UnitResult result = UnitUtil.getConvertedValue(new BigDecimal(itemApplication.getLastvalue()), itemApplication.getUnits());
        bandWidthDto.setBandWidthUnits(result.getUnits());
        bandWidthDto.setUpBandWidth(result.getValue());
        bandWidthDto.setDownBandWidth(result.getValue());
        return bandWidthDto;
    }

    @Override
    public List<MwLinkTargetIpInfo> getTargetIpInfo(LinkParam linkParam) throws Exception {
        LinkDetectionWayEnum detectionWayEnum = LinkDetectionWayEnum.getLinkDelectionWayEnum(linkParam.getDetectionWay());
        List<MwLinkTargetIpInfo> ipInfo = detectionWayManage.getIpInfo(detectionWayEnum, linkParam);
        return ipInfo;
    }

    /**
     * 获取设备信息
     */
    @Override
    public List<AssetInfo> getDeviceInfo() throws Exception {
        AssetsSearchParam searchParam = new AssetsSearchParam();
        searchParam.setEnableAssetsStatus(false);
        List<AssetInfo> assetInfos = assetsService.searchAssets(searchParam);
        return assetInfos;
    }

    @Override
    public List<LinkHistoryTrendDto> getLinkHistoryTrendInfo(LinkParam linkParam) throws Exception {
        String linkId = linkParam.getLinkId();
        Query query = new Query();
        query.addCriteria(CriteriaWrapper.where(MwNetWorkLinkDto::getLinkId).is(linkId));
        //获取线路信息
        MwNetWorkLinkDto netWorkLinkDto = netWorkLinkMapper.findOne(query);
        String detectionWay = netWorkLinkDto.getDetectionWay();
        LinkDetectionWayEnum linkDetectionWayEnum = LinkDetectionWayEnum.getLinkDelectionWayEnum(detectionWay);
        //调用不同的策略处理
        List<LinkHistoryTrendDto> linkHistoryTrendData = detectionWayManage.getLinkHistoryTrendData(linkDetectionWayEnum, netWorkLinkDto, linkParam);
        return linkHistoryTrendData;
    }

    @Override
    public MwNetWorkLinkDto selectLinkByLinkId(LinkParam linkParam) throws Exception {
        String linkId = linkParam.getLinkId();
        Query query = new Query();
        query.addCriteria(CriteriaWrapper.where(MwNetWorkLinkDto::getLinkId).is(linkId));
        //获取线路信息
        MwNetWorkLinkDto netWorkLinkDto = netWorkLinkMapper.findOne(query);
        if(netWorkLinkDto != null && CollectionUtils.isEmpty(netWorkLinkDto.getGroups())){
            netWorkLinkDto.setGroups(new ArrayList<>());
        }
        return netWorkLinkDto;
    }

    @Override
    public void saveLinkTree(MwLinkTreeDto linkTreeDto) {
        if(StringUtils.isEmpty(linkTreeDto.getId())){
            linkTreeDto.setId(moduleIDManager.getIDStr(IDModelType.MyMonitor));
        }
        linkTreeMapper.save(linkTreeDto);
    }

    @Override
    public List<MwLinkTreeDto> selectLinkTree() {
        List<MwLinkTreeDto> linkTreeDtos = linkTreeMapper.find(new Query());
        if(CollectionUtils.isEmpty(linkTreeDtos)){return linkTreeDtos;}
        //查询所有线路
        List<MwNetWorkLinkDto> workLinkDtos = netWorkLinkMapper.find(new Query());
        associationLinkAndLinkTree(linkTreeDtos,workLinkDtos);
        List<MwLinkTreeDto> tree = buildTree(linkTreeDtos);
        for (MwLinkTreeDto mwLinkTreeDto : tree) {
            mergeLinkIds(mwLinkTreeDto);
        }
        TreeUtils.sortTree(tree, DatabaseUtils.getFieldName(MwLinkTreeDto::getLinkTreeName),DatabaseUtils.getFieldName(MwLinkTreeDto::getLinkTreeName));
        return tree;
    }

    private void associationLinkAndLinkTree(List<MwLinkTreeDto> linkTreeDtos,List<MwNetWorkLinkDto> workLinkDtos){
        if(CollectionUtils.isEmpty(workLinkDtos)){
           return;
        }
        Map<String, List<String>> linkMap = workLinkDtos.stream().filter(item -> item.getLinkGroup() != null).collect(Collectors.groupingBy(MwNetWorkLinkDto::getLinkGroup, Collectors.mapping(MwNetWorkLinkDto::getLinkId, Collectors.toList())));
        if(linkMap == null || linkMap.isEmpty()){return;}
        for (Map.Entry<String, List<String>> entry : linkMap.entrySet()) {
            String linkTreeId = entry.getKey();
            List<MwLinkTreeDto> treeDtos = linkTreeDtos.stream().filter(item -> item.getId().equals(linkTreeId)).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(treeDtos)){continue;}
            MwLinkTreeDto treeDto = treeDtos.get(0);
            treeDto.setLinkIds(entry.getValue());
            treeDto.setLinkCount(entry.getValue() == null?0:entry.getValue().size());
        }
    }


    @Override
    public void delLinkTree(LinkParam linkParam) throws Exception {
        String linkTreeId = linkParam.getLinkTreeId();
        if (StringUtils.isEmpty(linkTreeId)){return;}
        //查询改分组有没有线路，有线路不允许删除
        Query query = new Query();
        query.addCriteria(CriteriaWrapper.where(MwNetWorkLinkDto::getLinkGroup).is(linkTreeId));
        long count = netWorkLinkMapper.count(query);
        if(count > 0){
            throw new WarnTitleException("link-tree-delete-prompt");
        }
        //删除数据
        Query removeQuery = new Query();
        removeQuery.addCriteria(new Criteria(CMDBTool.getFieldName(MwLinkTreeDto::getId)).in(linkParam.getLinkTreeId()));
        linkTreeMapper.remove(removeQuery);
    }

    @Override
    public List<MwNetWorkLinkDto> selectLinkByInstanceIds(List<String> instanceId) throws Exception {
        List<Criteria> criteriaList = new ArrayList<>();
        Criteria criteriaTargetIpId = new Criteria(CMDBTool.getFieldName(MwNetWorkLinkDto::getDetectionTargetIpId)).in(instanceId);
        criteriaList.add(criteriaTargetIpId);
        //取数端口源设备，需要查询源设备的资产ID
        Criteria criteriaRoot = new Criteria(CMDBTool.getFieldName(MwNetWorkLinkDto::getTakeValuePort)).is(LinkFetchPortEnum.ROOT.getType());
        Criteria criteriaRootId = new Criteria(CMDBTool.getFieldName(MwNetWorkLinkDto::getSourceDeviceAsset)).in(instanceId);
        Criteria rootCriteria = new Criteria();
        rootCriteria.andOperator(Arrays.asList(criteriaRoot,criteriaRootId));
        criteriaList.add(rootCriteria);
        //取数端口目标设备，需要查询目标设备的ID
        Criteria criteriaTarget = new Criteria(CMDBTool.getFieldName(MwNetWorkLinkDto::getTakeValuePort)).is(LinkFetchPortEnum.TARGET.getType());
        Criteria criteriaTargetId = new Criteria(CMDBTool.getFieldName(MwNetWorkLinkDto::getTargetDeviceAsset)).in(instanceId);
        Criteria targetCriteria = new Criteria();
        targetCriteria.andOperator(Arrays.asList(criteriaTarget,criteriaTargetId));
        criteriaList.add(targetCriteria);
        Query query = new Query(new Criteria().orOperator(criteriaList));
        List<MwNetWorkLinkDto> linkDtos = netWorkLinkMapper.find(query);
        return linkDtos;
    }

    @Override
    public void linkImport(MultipartFile file,HttpServletResponse response) throws Exception {
        if(file == null){
            throw new WarnTitleException("upload-file-empty");
        }
        String fileName = file.getOriginalFilename();
        if(!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")){
            throw new WarnTitleException("link-import-file-format");
        }
        //读excel内容到实体
        linkImportManager.importData(file, cmdbServiceManage, linkTreeMapper,this,response);
    }

    @Override
    public void exportLinkTemplate(HttpServletResponse response) throws Exception {
        linkImportManager.exportTemplate(response,linkTreeMapper,cmdbServiceManage);
    }

    @Override
    public void linkExport(LinkParam linkParam, HttpServletResponse response) throws Exception {
        //查询需要导出的线路数据
        linkParam.setPageNum(1);
        linkParam.setPageSize(Integer.MAX_VALUE);
        Page page = selectList(linkParam);
        List records = page.getRecords();
        linkImportManager.exportLinkInfo(records,response,cmdbServiceManage,linkTreeMapper);
    }


    public List<MwLinkTreeDto> buildTree(List<MwLinkTreeDto> dtos) {
        Map<String, MwLinkTreeDto> dtoMap = dtos.stream()
                .collect(Collectors.toMap(MwLinkTreeDto::getId, dto -> dto));
        List<MwLinkTreeDto> rootList = new ArrayList<>();
        for (MwLinkTreeDto dto : dtos) {
            if (StringUtils.isEmpty(dto.getParentId())) {
                rootList.add(dto);
            } else {
                MwLinkTreeDto parent = dtoMap.get(dto.getParentId());
                if (parent != null) {
                    if (CollectionUtils.isEmpty(parent.getChildren())) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(dto);
                }
            }
        }
        return rootList;
    }

    public void mergeLinkIds(MwLinkTreeDto node) {
        if (node.getChildren() != null) {
            for (MwLinkTreeDto child : node.getChildren()) {
                mergeLinkIds(child);
                if (child.getLinkIds() != null) {
                    if (node.getLinkIds() == null) {
                        node.setLinkIds(new ArrayList<>());
                        node.setLinkCount(0);
                    }
                    node.getLinkIds().addAll(child.getLinkIds());
                    node.setLinkCount(node.getLinkCount()+child.getLinkIds().size());
                }
            }
        }
        if(node.getChildren() == null && node.getLinkIds() == null){
            node.setLinkIds(new ArrayList<>());
        }
    }

    @Override
    protected MwNetWorkLinkDto genObject() {
        return new MwNetWorkLinkDto();
    }
}
